Skip to content

feat: harden AnonVote contract with validation, error taxonomy, admin… - #95

Merged
Just-Bamford merged 2 commits into
AnonVote:mainfrom
michaelvic123:main
Jul 30, 2026
Merged

feat: harden AnonVote contract with validation, error taxonomy, admin…#95
Just-Bamford merged 2 commits into
AnonVote:mainfrom
michaelvic123:main

Conversation

@michaelvic123

Copy link
Copy Markdown
Contributor

Hardening AnonVote Soroban Contract
Input validation

  • All write paths (record_ballot, record_token, record_vote, record_result) validate hashes via shared validate_hex_hash — rejects non-64-char strings, uppercase, and non-hex characters
  • initialize rejects zero address (GAAA...A)
  • rotate_admin rejects zero address and self-rotation
    State guards
  • Explicit DataKey::Initialized flag prevents re-initialization (was implicit via Admin presence)
  • record_token / record_vote / record_result check ballot existence → BallotNotFound
  • record_token / record_vote / record_result check finalisation → BallotAlreadyFinalised
  • record_ballot rejects duplicate hashes → BallotAlreadyExists
    Error taxonomy (errors.rs)
    10 stable #[repr(u32)] discriminants (must never change post-deployment):
  • AlreadyInitialized(1), Unauthorized(2), BallotAlreadyExists(3), BallotNotFound(4), BallotAlreadyFinalised(5), InvalidBallotIdHash(6), InvalidResultHash(7), InvalidAdminAddress(8), CounterOverflow(9), BallotExpired(10)
    Overflow detection
  • u32::MAX guard on token/vote counters returns CounterOverflow + emits ("counter", "ovrflw") event
    Admin rotation
  • rotate_admin stores rotation history as Vec (old_admin, new_admin, timestamp)
  • New get_admin_history view function
    Breaking changes from previous behaviour
  • Old idempotent re-record removed: record_ballot with existing hash always fails (BallotAlreadyExists)
  • Old idempotent re-record removed: record_result with any hash on a finalised ballot fails (BallotAlreadyFinalised)
  • Event topics renamed from ("audit", "blt_crtd") → ("ballot", "regstrd") etc.
    Testing (29 cases)
    initialize guards, hash validation (length/uppercase/non-hex), duplicate detection, ballot-not-found, finalisation guards, overflow at u32::MAX (with non-panicking isolation), admin rotation (success, same-address, zero-address, unauthorized, history growth), result hash validation, is_consistent for active/inconsistent/nonexistent ballots.
    Stability
    STABILITY.md documents that error discriminants, storage keys, and event topics are immutable post-deployment.

closes #90

@Just-Bamford
Just-Bamford merged commit 266f444 into AnonVote:main Jul 30, 2026
1 of 2 checks passed
@grantfox-oss grantfox-oss Bot mentioned this pull request Jul 30, 2026
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Contract validation and error handling

2 participants